/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


/*************************************************************************
 * File: event.cpp
 *************************************************************************
 *\author: starlove
 *************************************************************************/

#include <network/event.h>
#include <platform/timer.h>

CFixedAllocator<EVENT> g_Events;

LPEVENT Create_Event()
{
    LPEVENT ev = g_Events.allocate();
    if (!ev)
    {
        return NULL;
    }
    memset(ev, 0, sizeof(EVENT));
    return ev;
}

void Destory_Event(LPEVENT pev)
{
	g_Events.release(pev);
}

LPEventIO CEventDispatcher::GetIO()
{
	return m_io;
}

CEventDispatcher::CEventDispatcher()
{
    m_io = NULL;
    m_frame_time = __DEFAULT_EVENT_FRAME_TIME__;
    m_running = false;
}

bool CEventDispatcher::Init(LPEventIO io, unsigned int frame_time /* = __DEFAULT_EVENT_FRAME_TIME__ */)
{
    if (!io)
        return false;
    m_io = io;
    m_frame_time = frame_time;
    m_running = true;
    return true;
}

void CEventDispatcher::Abort()
{
    m_running = false;
}

bool CEventDispatcher::Bind(EVHANDLE hd)
{
    if (!m_io)
        return false;
    return m_io->Bind(hd);
}

void CEventDispatcher::Lookup()
{
    unsigned int uev_count = 100;
    LPEVENT evs = m_io->Query(uev_count, __DEFAULT_EVENT_FRAME_TIME__);
    LPEVENT ev_curr = evs;
	//if(ev_curr)
		//DEBUG_INFO_NETWORK(0,"Query Complete, op: %p", ev_curr->op);
    while (ev_curr)
    {
        LPEventProcessor ep = (LPEventProcessor)ev_curr->op;
        if(ep)
		{
			//DEBUG_INFO_NETWORK(0, "ep Event %d", ev_curr->event_sets);
			ep->OnEvent(ev_curr, ev_curr->event_sets);
			//DEBUG_INFO_NETWORK(0, "ep Event %d Processed", ev_curr->event_sets);
		}else
		{
			//DEBUG_INFO_NETWORK(0, "ep is NULL");
		}

        LPEVENT ev = ev_curr;
        ev_curr = (LPEVENT)ev_curr->next;

        Destory_Event(ev);
    }

    ITimer::CheckAllTimers();
}

void CEventDispatcher::Post(LPEVENT ev)
{
    if (!m_io)
        return;
    m_io->Post(ev);
}
